/*   1:    */ package nl.siegmann.epublib.utilities;
/*   2:    */ 
/*   3:    */ import java.io.Reader;
/*   4:    */ import java.io.StringWriter;
/*   5:    */ import java.util.ArrayList;
/*   6:    */ import java.util.List;
/*   7:    */ import javax.xml.namespace.QName;
/*   8:    */ import javax.xml.stream.XMLEventFactory;
/*   9:    */ import javax.xml.stream.XMLEventReader;
/*  10:    */ import javax.xml.stream.XMLEventWriter;
/*  11:    */ import javax.xml.stream.XMLInputFactory;
/*  12:    */ import javax.xml.stream.XMLOutputFactory;
/*  13:    */ import javax.xml.stream.XMLStreamException;
/*  14:    */ import javax.xml.stream.events.EndElement;
/*  15:    */ import javax.xml.stream.events.StartElement;
/*  16:    */ import javax.xml.stream.events.XMLEvent;
/*  17:    */ 
/*  18:    */ public class HtmlSplitter
/*  19:    */ {
/*  20: 24 */   private XMLEventFactory xmlEventFactory = XMLEventFactory.newInstance();
/*  21: 25 */   private XMLOutputFactory xmlOutputFactory = XMLOutputFactory.newInstance();
/*  22: 26 */   private List<XMLEvent> headerElements = new ArrayList();
/*  23: 27 */   private List<XMLEvent> footerElements = new ArrayList();
/*  24:    */   private int footerCloseTagLength;
/*  25: 29 */   private List<XMLEvent> elementStack = new ArrayList();
/*  26: 30 */   private StringWriter currentDoc = new StringWriter();
/*  27: 31 */   private List<XMLEvent> currentXmlEvents = new ArrayList();
/*  28:    */   private XMLEventWriter out;
/*  29: 33 */   private int maxLength = 300000;
/*  30: 34 */   private List<List<XMLEvent>> result = new ArrayList();
/*  31:    */   
/*  32:    */   public List<List<XMLEvent>> splitHtml(Reader reader, int maxLength)
/*  33:    */     throws XMLStreamException
/*  34:    */   {
/*  35: 37 */     XMLEventReader xmlEventReader = XMLInputFactory.newInstance().createXMLEventReader(reader);
/*  36: 38 */     return splitHtml(xmlEventReader, maxLength);
/*  37:    */   }
/*  38:    */   
/*  39:    */   private static int calculateTotalTagStringLength(List<XMLEvent> xmlEvents)
/*  40:    */   {
/*  41: 42 */     int result = 0;
/*  42: 43 */     for (XMLEvent xmlEvent : xmlEvents) {
/*  43: 44 */       result += xmlEvent.toString().length();
/*  44:    */     }
/*  45: 46 */     return result;
/*  46:    */   }
/*  47:    */   
/*  48:    */   public List<List<XMLEvent>> splitHtml(XMLEventReader reader, int maxLength)
/*  49:    */     throws XMLStreamException
/*  50:    */   {
/*  51: 50 */     this.headerElements = getHeaderElements(reader);
/*  52: 51 */     this.footerElements = getFooterElements();
/*  53: 52 */     this.footerCloseTagLength = calculateTotalTagStringLength(this.footerElements);
/*  54: 53 */     this.maxLength = ((int)(maxLength * 0.9D));
/*  55: 54 */     this.currentXmlEvents = new ArrayList();
/*  56: 55 */     this.currentXmlEvents.addAll(this.headerElements);
/*  57: 56 */     this.currentXmlEvents.addAll(this.elementStack);
/*  58: 57 */     this.out = this.xmlOutputFactory.createXMLEventWriter(this.currentDoc);
/*  59: 58 */     for (XMLEvent headerXmlEvent : this.headerElements) {
/*  60: 59 */       this.out.add(headerXmlEvent);
/*  61:    */     }
/*  62: 61 */     XMLEvent xmlEvent = reader.nextEvent();
/*  63: 62 */     while (!isBodyEndElement(xmlEvent))
/*  64:    */     {
/*  65: 63 */       processXmlEvent(xmlEvent, this.result);
/*  66: 64 */       xmlEvent = reader.nextEvent();
/*  67:    */     }
/*  68: 66 */     this.result.add(this.currentXmlEvents);
/*  69: 67 */     return this.result;
/*  70:    */   }
/*  71:    */   
/*  72:    */   private void closeCurrentDocument()
/*  73:    */     throws XMLStreamException
/*  74:    */   {
/*  75: 72 */     closeAllTags(this.currentXmlEvents);
/*  76: 73 */     this.currentXmlEvents.addAll(this.footerElements);
/*  77: 74 */     this.result.add(this.currentXmlEvents);
/*  78:    */   }
/*  79:    */   
/*  80:    */   private void startNewDocument()
/*  81:    */     throws XMLStreamException
/*  82:    */   {
/*  83: 78 */     this.currentDoc = new StringWriter();
/*  84: 79 */     this.out = this.xmlOutputFactory.createXMLEventWriter(this.currentDoc);
/*  85: 80 */     for (XMLEvent headerXmlEvent : this.headerElements) {
/*  86: 81 */       this.out.add(headerXmlEvent);
/*  87:    */     }
/*  88: 83 */     for (XMLEvent stackXmlEvent : this.elementStack) {
/*  89: 84 */       this.out.add(stackXmlEvent);
/*  90:    */     }
/*  91: 87 */     this.currentXmlEvents = new ArrayList();
/*  92: 88 */     this.currentXmlEvents.addAll(this.headerElements);
/*  93: 89 */     this.currentXmlEvents.addAll(this.elementStack);
/*  94:    */   }
/*  95:    */   
/*  96:    */   private void processXmlEvent(XMLEvent xmlEvent, List<List<XMLEvent>> docs)
/*  97:    */     throws XMLStreamException
/*  98:    */   {
/*  99: 93 */     this.out.flush();
/* 100: 94 */     String currentSerializerDoc = this.currentDoc.toString();
/* 101: 95 */     if (currentSerializerDoc.length() + xmlEvent.toString().length() + this.footerCloseTagLength >= this.maxLength)
/* 102:    */     {
/* 103: 96 */       closeCurrentDocument();
/* 104: 97 */       startNewDocument();
/* 105:    */     }
/* 106: 99 */     updateStack(xmlEvent);
/* 107:100 */     this.out.add(xmlEvent);
/* 108:101 */     this.currentXmlEvents.add(xmlEvent);
/* 109:    */   }
/* 110:    */   
/* 111:    */   private void closeAllTags(List<XMLEvent> xmlEvents)
/* 112:    */     throws XMLStreamException
/* 113:    */   {
/* 114:105 */     for (int i = this.elementStack.size() - 1; i >= 0; i--)
/* 115:    */     {
/* 116:106 */       XMLEvent xmlEvent = (XMLEvent)this.elementStack.get(i);
/* 117:107 */       XMLEvent xmlEndElementEvent = this.xmlEventFactory.createEndElement(xmlEvent.asStartElement().getName(), null);
/* 118:108 */       xmlEvents.add(xmlEndElementEvent);
/* 119:    */     }
/* 120:    */   }
/* 121:    */   
/* 122:    */   private void updateStack(XMLEvent xmlEvent)
/* 123:    */   {
/* 124:113 */     if (xmlEvent.isStartElement())
/* 125:    */     {
/* 126:114 */       this.elementStack.add(xmlEvent);
/* 127:    */     }
/* 128:115 */     else if (xmlEvent.isEndElement())
/* 129:    */     {
/* 130:116 */       XMLEvent lastEvent = (XMLEvent)this.elementStack.get(this.elementStack.size() - 1);
/* 131:117 */       if ((lastEvent.isStartElement()) && (xmlEvent.asEndElement().getName().equals(lastEvent.asStartElement().getName()))) {
/* 132:119 */         this.elementStack.remove(this.elementStack.size() - 1);
/* 133:    */       }
/* 134:    */     }
/* 135:    */   }
/* 136:    */   
/* 137:    */   private List<XMLEvent> getHeaderElements(XMLEventReader reader)
/* 138:    */     throws XMLStreamException
/* 139:    */   {
/* 140:125 */     List<XMLEvent> result = new ArrayList();
/* 141:126 */     XMLEvent event = reader.nextEvent();
/* 142:127 */     while ((event != null) && (!isBodyStartElement(event)))
/* 143:    */     {
/* 144:128 */       result.add(event);
/* 145:129 */       event = reader.nextEvent();
/* 146:    */     }
/* 147:133 */     if (event != null) {
/* 148:134 */       result.add(event);
/* 149:    */     }
/* 150:136 */     return result;
/* 151:    */   }
/* 152:    */   
/* 153:    */   private List<XMLEvent> getFooterElements()
/* 154:    */     throws XMLStreamException
/* 155:    */   {
/* 156:140 */     List<XMLEvent> result = new ArrayList();
/* 157:141 */     result.add(this.xmlEventFactory.createEndElement("", null, "body"));
/* 158:142 */     result.add(this.xmlEventFactory.createEndElement("", null, "html"));
/* 159:143 */     result.add(this.xmlEventFactory.createEndDocument());
/* 160:144 */     return result;
/* 161:    */   }
/* 162:    */   
/* 163:    */   private static boolean isBodyStartElement(XMLEvent xmlEvent)
/* 164:    */   {
/* 165:148 */     return (xmlEvent.isStartElement()) && (xmlEvent.asStartElement().getName().getLocalPart().equals("body"));
/* 166:    */   }
/* 167:    */   
/* 168:    */   private static boolean isBodyEndElement(XMLEvent xmlEvent)
/* 169:    */   {
/* 170:152 */     return (xmlEvent.isEndElement()) && (xmlEvent.asEndElement().getName().getLocalPart().equals("body"));
/* 171:    */   }
/* 172:    */ }


/* Location:           C:\Users\David\workspace\CosaRaraPorqueSi\main\epublib-tools-3.1.jar
 * Qualified Name:     nl.siegmann.epublib.utilities.HtmlSplitter
 * JD-Core Version:    0.7.0.1
 */